<script setup lang="ts">
import { computed, defineExpose, ref, watchEffect } from 'vue'
import type { VxeGridInstance, VxeGridProps } from 'vxe-table'
import { Setting } from '@element-plus/icons-vue'
import TableColumnSetting from './TableColumnSetting.vue'
import type { ExtendedColumnConfig } from '@/types/table'

interface Props {
  /** 列配置 */
  columns: ExtendedColumnConfig[]
  /** 表格数据 */
  data: any[]
  /** 表格高度 */
  height?: string | number
  /** 是否显示设置按钮 */
  showSettings?: boolean
  /** 额外的 VXE Grid 配置 */
  gridOptions?: Partial<VxeGridProps>
}

interface Emits {
  /** 列宽调整事件 */
  (e: 'column-resize', params: any): void
}

const props = withDefaults(defineProps<Props>(), {
  height: '100%',
  showSettings: true,
  gridOptions: () => ({}),
})

const emit = defineEmits<Emits>()

// 表格实例引用
const tableRef = ref<VxeGridInstance>()

// 原始列配置
const originalColumns = ref<ExtendedColumnConfig[]>([...props.columns])

// 当前列配置
const currentColumns = ref<ExtendedColumnConfig[]>([...props.columns])

// 数据加载状态
const isLoadingData = ref(false)

// 计算属性：过滤可见列并排序
const visibleColumns = computed(() => {
  return currentColumns.value
    .filter((col) => col.visible !== false)
    .sort((a, b) => (a.sortIndex || 0) - (b.sortIndex || 0))
    .map((col) => {
      // 创建VXE表格需要的列配置
      const vxeCol: any = { ...col }

      // 应用自定义样式
      if (col.color || col.textColor) {
        vxeCol.headerClassName = `custom-header-${col.field || col.type || 'default'}`
        vxeCol.className = `custom-cell-${col.field || col.type || 'default'}`
      }

      // 移除自定义属性，避免传给VXE表格
      delete vxeCol.visible
      delete vxeCol.color
      delete vxeCol.textColor
      delete vxeCol.sortIndex
      return vxeCol
    })
})

// 合并的表格配置
const mergedGridOptions = computed<VxeGridProps>(() => ({
  columns: visibleColumns.value,
  resizable: true,
  data: props.data,
  border: true,
  showOverflow: true,
  align: 'center',
  cellConfig: { height: 35 },
  height: props.height,
  ...props.gridOptions,
}))

/**
 * 恢复默认配置
 */
const restoreDefaultColumns = () => {
  currentColumns.value = [...originalColumns.value]
  settingsVisible.value = false
}

/**
 * 表格设置相关状态
 */
const settingsVisible = ref(false)

/**
 * 处理列配置变化
 */
const handleColumnsChange = (newColumns: ExtendedColumnConfig[]) => {
  currentColumns.value = [...newColumns]
}

/**
 * 打开设置对话框
 */
const openSettings = () => {
  settingsVisible.value = true
}

/**
 * 处理列宽调整事件
 */
const handleColumnResize = (params: any) => {
  const { column, newWidth } = params
  const fieldKey = column.field || column.type

  // 更新本地列配置中的宽度
  const targetColumn = currentColumns.value.find((col) => (col.field || col.type) === fieldKey)

  if (targetColumn && newWidth) {
    targetColumn.width = newWidth
  }

  // 抛出事件给父组件
  emit('column-resize', params)
}

/**
 * 动态生成CSS样式
 */
const generateDynamicStyles = () => {
  const styleSheet = document.getElementById('dynamic-column-styles') as HTMLStyleElement
  if (styleSheet) {
    styleSheet.remove()
  }

  const style = document.createElement('style')
  style.id = 'dynamic-column-styles'

  let cssRules = ''
  currentColumns.value.forEach((col) => {
    const fieldName = col.field || col.type || 'default'
    if (col.color || col.textColor) {
      // 表头样式
      if (col.color) {
        cssRules += `.custom-header-${fieldName} { background-color: ${col.color} !important; }`
      }
      if (col.textColor) {
        cssRules += `.custom-header-${fieldName} { color: ${col.textColor} !important; }`
      }

      // 单元格样式
      if (col.color) {
        cssRules += `.custom-cell-${fieldName} { background-color: ${col.color} !important; }`
      }
      if (col.textColor) {
        cssRules += `.custom-cell-${fieldName} { color: ${col.textColor} !important; }`
      }
    }
  })

  style.textContent = cssRules
  document.head.appendChild(style)
}

// 监听列配置变化，动态更新样式
watchEffect(() => {
  generateDynamicStyles()
})

// 监听 props.columns 变化，同步更新本地状态
watchEffect(() => {
  originalColumns.value = [...props.columns]
  currentColumns.value = [...props.columns]
})

// 控制数据加载状态的方法
const setLoadingData = (loading: boolean) => {
  isLoadingData.value = loading
}

// 暴露给父组件的方法和属性
defineExpose({
  tableRef,
  restoreDefault: restoreDefaultColumns,
  openSettings,
  currentColumns: computed(() => currentColumns.value),
  isLoadingData: computed(() => isLoadingData.value),
  setLoadingData,
})
</script>

<template>
  <div class="configurable-table">
    <!-- 表格设置按钮 -->
    <div v-if="showSettings" class="table-toolbar">
      <el-button type="primary" @click="openSettings">
        <el-icon>
          <Setting />
        </el-icon>
        表格设置
      </el-button>
    </div>

    <div class="table-container">
      <vxe-grid
        ref="tableRef"
        v-bind="mergedGridOptions"
        @resizable-change="handleColumnResize"
        :loading="isLoadingData"
      >
        <!-- 动态插槽 -->
        <template
          v-for="col in visibleColumns"
          :key="col.field || col.type"
          #[col.slots?.default]="scope"
        >
          <slot :name="col.slots?.default" v-bind="scope" />
        </template>
      </vxe-grid>
    </div>

    <!-- 表格列设置组件 -->
    <TableColumnSetting
      v-if="showSettings"
      v-model="settingsVisible"
      :columns="currentColumns"
      @columns-change="handleColumnsChange"
      @restore-default="restoreDefaultColumns"
    />
  </div>
</template>

<style scoped lang="scss">
.configurable-table {
  height: 100%;

  .table-toolbar {
    margin-bottom: 16px;
    display: flex;
    justify-content: flex-end;
  }

  .table-container {
    height: 100%;
  }
}
</style>
